package host.springboot.framework.core.exception;

import host.springboot.framework.core.enumeration.BaseEnum;
import host.springboot.framework.core.util.inner.StringUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

/**
 * 全局自定义异常基类
 *
 * <p>该类为全局自定义异常基类, 为避免部分功能失效, 项目中所有的自定义异常原则上都必须继承该类
 *
 * @author JiYinchuan
 * @since 1.0.0
 */
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class ApplicationException extends RuntimeException {

    public static final String DEFAULT_ERROR_USER_TIP = "网络开小差了, 请稍后再试 (╯﹏╰)";

    /**
     * 错误码
     */
    protected final String errorCode;

    /**
     * 错误信息
     */
    protected final String errorMessage;

    /**
     * 用户提示信息
     */
    protected final String userTip;

    /**
     * 错误枚举
     */
    protected final BaseEnum<String> baseEnum;

    /**
     * 构造器
     *
     * @param baseEnum 枚举基类
     * @see host.springboot.framework.core.enumeration.error
     * @since 1.0.0
     */
    public ApplicationException(@NonNull BaseEnum<String> baseEnum) {
        super("errorCode: " + baseEnum.getValue() + ", errorMessage: " + baseEnum.getReasonPhrase());
        this.errorCode = baseEnum.getValue();
        this.errorMessage = baseEnum.getReasonPhrase();
        this.baseEnum = baseEnum;
        userTip = DEFAULT_ERROR_USER_TIP;
    }

    /**
     * 构造器
     *
     * @param baseEnum 枚举基类
     * @param userTip  用户提示信息
     * @since 1.0.0
     */
    public ApplicationException(@NonNull BaseEnum<String> baseEnum, @Nullable String userTip) {
        super("errorCode: " + baseEnum.getValue() + ", errorMessage: " + baseEnum.getReasonPhrase() + ", userTip: " + userTip);
        this.errorCode = baseEnum.getValue();
        this.errorMessage = baseEnum.getReasonPhrase();
        this.userTip = StringUtils.defaultString(userTip, DEFAULT_ERROR_USER_TIP);
        this.baseEnum = baseEnum;
    }

    /**
     * 构造器
     *
     * @param errorCode    错误码
     * @param errorMessage 错误信息
     * @param userTip      用户提示信息
     * @since 1.0.0
     */
    public ApplicationException(@NonNull String errorCode, @NonNull String errorMessage, @Nullable String userTip) {
        super("errorCode: " + errorCode + ", errorMessage: " + errorMessage + ", userTip: " + userTip);
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
        this.userTip = StringUtils.defaultString(userTip, DEFAULT_ERROR_USER_TIP);
        this.baseEnum = new BaseEnum<String>() {
            @Override
            public String getValue() {
                return errorCode;
            }

            @Override
            public String getReasonPhrase() {
                return errorMessage;
            }
        };
    }
}
